package com.stanwind.netty.core;

import com.stanwind.netty.api.ClientUtils;
import com.stanwind.netty.api.Log;
import com.stanwind.netty.api.RoomUtils;
import com.stanwind.netty.constant.Command;
import com.stanwind.netty.core.protocol.model.Request;
import com.stanwind.netty.domain.pojo.Player;
import com.stanwind.netty.handler.CommandReflect;
import com.stanwind.netty.handler.impl.EXITROOM;
import org.jboss.netty.channel.*;
import org.jboss.netty.handler.timeout.IdleState;
import org.jboss.netty.handler.timeout.IdleStateEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

/**
 * 消息路由
 *
 * @author StanWind
 */
@Service("router")
@Scope("prototype")
////特别注意这个注解@Sharable，默认的4版本不能自动导入匹配的包，需要手动加入
////地址是import io.netty.channel.ChannelHandler.Sharable;
@ChannelHandler.Sharable
public class Router extends SimpleChannelHandler implements Command {

    @Autowired
    private Log Log;

    @Override
    public void channelDisconnected(ChannelHandlerContext ctx,
                                    ChannelStateEvent e) throws Exception {
        //closed方法是必定触发 所以在closed里面处理
//        //调用退出房间
//        EXITROOM exitroom = applicationContext.getBean(EXITROOM.class);
//        exitroom.setCtx(ctx);
//        exitroom.handle();
//        log.getLogger().info("channelDisconnected");
//        super.channelDisconnected(ctx, e);

    }

    @Autowired
    private RoomUtils roomUtils;

    @Autowired
    private ClientUtils clientUtils;

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
            throws Exception {
        //调用退出房间
        EXITROOM exitroom = applicationContext.getBean(EXITROOM.class);
        exitroom.setCtx(ctx);
        exitroom.handle();
        log.getLogger().info("channelClosed");
        super.channelClosed(ctx, e);


//        PlayerCustomer player = LoginList.getPlayer(ctx.getChannel().getId());
//        if (player != null) {
//            Log.getLogger().debug("强制关闭");
//            EXITROOM.process(player);       //	退出房间
//            EXITGAME.process(ctx);          //	退出游戏
//        }
    }

    @Override
    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
            throws Exception {
//        //System.out.println(ctx.getChannel().getId());
//        Response response = new Response();
//        SecureResponse secureResponse = new SecureResponse();
//        response.setCmd(CMD_SECURE);
//        response.setData(secureResponse.getBytes());
//        ctx.getChannel().write(response);
        //ServerLog.getLogger().debug("Seucre Check");
        //log.getLogger().info(ctx.getChannel().getId()+"-------------------------------------------");
        super.channelConnected(ctx, e);

    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
            throws Exception {

//        PlayerCustomer player = LoginList.getPlayer(ctx.getChannel().getId());
//        if (player != null) {
//            Log.getLogger().error("ExecptionCaought", e);
//            EXITROOM.process(player);       //	退出房间
//            EXITGAME.process(ctx);          //	退出游戏
//        }
        log.getLogger().info("exception"+e);
        super.exceptionCaught(ctx, e);

    }

    @Autowired
    private Log log;

    @Autowired
    private CommandReflect commandReflect;

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
            throws Exception {
        Request request = (Request) e.getMessage();
        short cmd = request.getCmd();
        if (cmd != CMD_SECURE)
            log.getLogger().info(String.format("cmd---->0x%H", cmd));
        //反射调用处理方法
        commandReflect.handle(cmd, ctx, request);
    }
    /**
     * 心跳检测
     */
//    @Override
//    public void handleUpstream(final ChannelHandlerContext ctx, ChannelEvent e)
//            throws Exception {

//        if (e instanceof IdleStateEvent) {
//            if (((IdleStateEvent) e).getState() == IdleState.ALL_IDLE) {
//                System.out.println("time out");
//                ChannelFuture cf = ctx.getChannel().write(
//                        "time out, connection will be closed");
//                // when the client received the message,it would be closed
//                cf.addListener(new ChannelFutureListener() {
//                    @Override
//                    public void operationComplete(ChannelFuture future)
//                            throws Exception {
//                        // 移除临时客户数据
//                        LoginList.removePlayer(ctx.getChannel().getId());
//                        // closed connection
//                        ctx.getChannel().close();
//                    }
//                });
//            }
//
//        } else {
//            super.handleUpstream(ctx, e);
//        }
//    }


}
